package com.qrxl.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qrxl.util.JGAssert;
import com.qrxl.common.vo.BaseQuery;
import com.qrxl.enums.EnumMenuTabFlag;
import com.qrxl.user.entity.Menu;
import com.qrxl.user.entity.RoleMenu;
import com.qrxl.user.mapper.MenuMapper;
import com.qrxl.user.service.IMenuService;
import com.qrxl.user.service.IRoleMenuService;
import com.qrxl.user.vo.UserLoginInfo;
import com.qrxl.user.vo.req.MenuAddReq;
import com.qrxl.user.vo.req.MenuListReq;
import com.qrxl.user.vo.req.MenuUpdateReq;
import com.qrxl.user.vo.res.MenuTreeRes;
import com.qrxl.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单 服务实现类
 * </p>
 *
 * @author friday
 * @since 2020-12-05
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
    @Autowired
    IMenuService menuService;
    @Autowired
    IRoleMenuService roleMenuService;

    @Override
    public void add(MenuAddReq req) {
        checkParenId(req.getParentId());
        Menu menu = new Menu();
        BeanUtils.copyProperties(req, menu);
        if (menu.getTabFlag() == null) {
            menu.setTabFlag(EnumMenuTabFlag.NO.getCode());
        }
        getBaseMapper().insert(menu);
    }

    @Override
    public IPage<Menu> selectPage(BaseQuery baseQuery, MenuListReq req) {
        QueryWrapper wrappers = StringUtil.buildBaseQuery(new Menu(), baseQuery, req);
        IPage page = getBaseMapper().selectPage(new Page(baseQuery.getPage(), baseQuery.getPageSize()), wrappers);
        return page;
    }

    @Override
    public void updateVo(MenuUpdateReq req) {
        checkParenId(req.getParentId());
        Menu updateObj = new Menu();
        BeanUtils.copyProperties(req, updateObj);
        updateById(updateObj);
    }

    @Override
    public List<MenuTreeRes> queryAllMenu() {
        List<Menu> menuList = baseMapper.selectList(Wrappers.query());
        return covert(menuList);
    }

    @Override
    public List<MenuTreeRes> qeryUserMenus(UserLoginInfo ul) {
        List<Menu> menuList = baseMapper.qeryUserMenus(ul.getId());
        //如果存在上级ID,需要将上级ID添加到列表中
        List<Menu> listParent = new ArrayList<>();
        menuList.forEach(menu -> {
            addParent(listParent, menu);
        });
        //去重
        menuList.addAll(listParent.stream().filter(i -> !menuList.stream().anyMatch(j -> i.getId().equals(j.getId()))).collect(Collectors.toList()));
        return covert(menuList);
    }

    private void addParent(List<Menu> listParent, Menu menu) {
        if (StringUtils.isEmpty(menu.getParentId())) {
            return;
        }
        Menu parentMenu = menuService.getById(menu.getParentId());
        if (parentMenu == null) {
            return;
        }
        listParent.add(parentMenu);
        addParent(listParent, parentMenu);
    }


    @Override
    @Transactional
    public void delete(String id) {
        RoleMenu cond = new RoleMenu();
        cond.setMenuId(id);
        roleMenuService.remove(Wrappers.query(cond));
        removeById(id);
    }

    private List<MenuTreeRes> covert(List<Menu> menuList) {
        List<MenuTreeRes> listTree = menuList.stream()
                .filter(one -> one.getParentId() == null)
                .map(one -> {
                    MenuTreeRes tree = new MenuTreeRes();
                    BeanUtils.copyProperties(one, tree);
                    return tree;
                }).collect(Collectors.toList());

        listTree.forEach(one -> {
            one.setSubMenu(findSubMenu(one.getId(), menuList));
        });
        return listTree;
    }

    private List<MenuTreeRes> findSubMenu(String parentId, List<Menu> menuList) {
        List<MenuTreeRes> subMenuList = menuList.stream().filter(one -> parentId.equals(one.getParentId())).map(one -> {
            MenuTreeRes tree = new MenuTreeRes();
            BeanUtils.copyProperties(one, tree);
            return tree;
        }).collect(Collectors.toList());
        if (subMenuList.size() == 0) {
            return null;
        } else {
            subMenuList.forEach(one -> {
                one.setSubMenu(findSubMenu(one.getId(), menuList));
            });
            return subMenuList;
        }
    }

    private void checkParenId(String parentId) {
        if (StringUtils.isEmpty(parentId)) {
            return;
        }
        Menu parent = menuService.getById(parentId);
        JGAssert.notNull(parent, "上级ID无效");
        JGAssert.isTrue(parent.getParentId() == null, "上级ID只能是根菜单");
    }
}
